<h1>Pagination</h1>

<h2>Summary</h2>
<p>The main goal of these classes is to make it easy to paginate data. However, this is not monolithic or one size fits all solution. The pagination module provides a layered range of solutions in which developers can pick and choose to tailor the classes to their needs.</p>

<h2>Specific Goals</h2>
<ul>
    <li>Account for as many use cases as possible</li>
    <li>Stay flexible for extendability</li>
    <li>Take care of the messy details of pagination: url generation, maintaining state, dealing with the request.</li>
</ul>
<h2>Basics</h2>
<p>The base object in this pagination system is a Value Object that holds the values for the list and does the necessary calculations. This class can be used alone, but if you do, you are required to initialize it manually.</p>

<pre class="prettyprint lang-php"><code>$pager = new A_Pagination_Core($datasource);
$pager-&gt;setCurrentPage(intval($_GET['mypagevar']));
$pager-&gt;setNumItems(intval($_GET['mycountvar'])); 
</code></pre>


<p>This component also provides a class that extends the Core class and initializes itself from the HTTP Request so you don't have to initialize it manually. This class adds a process() method that will initialize the object for you:</p>

<pre class="prettyprint lang-php"><code>$pager = new A_Pagination_Request($datasource);
$pager-&gt;process(); 
</code></pre>

<p>This Core object does the necessary calculation and will return page numbers for the current first, last, next and previous pages, plus a range of page numbers around the current page. These are intended to provide the basic functionality on which to build classes to render paginated output.</p>

<p>This class takes a Datasource object passed to the constructor. These Datasources comply to a simple Adapter interface. This component will provide Adapters for arrays, PDO, MySQL, etc. A getItems() method is provided to retrieve the records for the currently displayed page.</p>

<p>The basic methods in its interface are:</p>

<pre class="prettyprint lang-php"><code>class A_Pagination_Core {
     function __construct($datasource)
     function isPage($number)
     function getPage($number)
     function getCurrentPage()
     function getFirstPage()
     function getLastPage()
     function getPageRange()
     function getNumItems()
     function getItems()
} 
</code></pre>


<h2>Layered Design</h2>
<p>This component is not monolithic. There are several levels of classes that use a Core object and provide support for rendering output. The lowest level of output support uses page numbers from a Core object and builds URLs. Using this class you can have complete control of your template:</p>

<pre class="prettyprint lang-php"><code>$url = new A_Pagination_Helper_Url($pager);
$out .= '&lt;a href="' . $url-&gt;previous() . '"&gt;Prev&lt;/a&gt; ";
$out .= '&lt;a href="' . $url-&gt;next('Next') . '"&gt;Next&lt;/a&gt; ";</code></pre>

<p>The next level of output support uses page numbers from a Core object and builds complete links (<a> tags). You an pass the name of a CSS class to this object to control link style:</a>

<pre class="prettyprint lang-php"><code>$link = new A_Pagination_Helper_Link($pager);
$out .= $link-&gt;previous('Prev', 'mylinkclass');
$out .= $link-&gt;next('Next', 'mylinkclass');</code></pre>

<h2>Use Case Example</h2>
<p>Here is an example of combining the classes to do a basic paginated list with links:</p>

<pre class="prettyprint lang-php"><code>// create a data object that has the interface needed by the Pager object
$datasource = new Datasource();
 
// create a request processor to set pager from GET parameters
$pager = new A_Pagination_Request($datasource);
 
// initialize using values from $_GET
$pager-&gt;process();
 
// create a "standard" view object to create pagination links
include 'A/Pagination/View/Standard.php';
$view = new A_Pagination_View_Standard($pager);
 
// display the data
echo '&lt;table border="1"&gt;';
foreach ($pager-&gt;getItems() as $row) {
    echo '&lt;tr&gt;';
    echo '&lt;td&gt;' . $row['id'] . '&lt;/td&gt;&lt;td&gt;' . $row['name'] . '&lt;/td&gt;';
    echo '&lt;/tr&gt;';
}
echo '&lt;/table&gt;';
 
// display the pagination links
echo $view-&gt;render(); </code></pre>


<h2>Additional Features</h2>
<ul>
    <li>There are a number of examples that show different ways the classes can be used -- from do-it-yourself to standalone.</li>
    <li>There is support for ORDER BY functionality to sort the list. There are methods to generate column heading links to sort any column ascending/descending. Sort order is maintained while paging.</li>
    <li>The total number of items in the datasource is persisted RESTfully so, for example, COUNT() is only called one for database datasources.</li>
    <li>Request parameter names can be changed to remove conflicts and allow multiple pagers on one page.</li>
    <li>Pagination state values can be saved in the session if you want to be able to resume in the list where you left off -- when editing records in CRUD for example.</li>
</ul>
<h2>DataGrid</h2>
<p>For the most automated use case, we will be providing a DataGrid that takes care of all HTML once the core classes have been finalized.</p>

<h2>Levels of Functionality</h2>
<p>We are trying to build a layered solution that allows people to pick the level they want to deal with. That is the reason why this component is build with a bunch of small, single purpose classes (besides that being a good practice ). So the levels, from lowest to highest, are:</p>

<h3>Page Numbers</h3>

<pre class="prettyprint lang-php"><code>$pager = new A_Pagination_Core($datasource);
echo $pager-&gt;getNextPage();</code></pre>

<p>Output: <b>8</b></p>

<h3>URLs</h3>

<pre class="prettyprint lang-php"><code>$pager = new A_Pagination_Core($datasource);
$url = new A_Pagination_Helper_Url($pager);
echo $url-&gt;next();</code></pre>

<p>Output: <b>http://mysite.com/mypage.php?page=8</b></p>

<h3>Links</h3>

<pre class="prettyprint lang-php"><code>$pager = new A_Pagination_Core($datasource);
$link = new A_Pagination_Helper_Link($pager);
echo $link-&gt;next();</code></pre>

<p>Output: <b>8</b> (Note this is a link (<a>) to the URL above</a>

<h3>Standard View Helper</h3>

<pre class="prettyprint lang-php"><code>$pager = new A_Pagination_Core($datasource);
$view = new A_Pagination_View_Standard($pager);
echo $view-&gt;render();</code></pre>

<p>Output: <b>First Prev 5 6 7 8 9 Next Last</b></p>

<h3>All-in-one</h3>

<pre class="prettyprint lang-php"><code>$view = new A_Pagination_Standalone($datasource);
echo $view-&gt;render();</code></pre>

<p>Output: <b>First Prev 5 6 7 8 9 Next Last</b></p>

<p>We have also discussed possibly implementing different View Helpers to allow you to do pagination links like Google, phpBB, Flikr, etc. (e.g. A_Pagination_View_Google). All of the core functionality to build those is in the lower layers.</p>

<p>It is also our intention to provide a simple DataGrid. (And we may do a Ajax-ified, edit-in-place version as well)</p>

<h3>Data Grid</h3>


<pre class="prettyprint lang-php"><code>$pager = new A_Pagination_Request($datasource);
$view = new A_Pagination_View_Datagrid($pager);
echo $view-&gt;render();</code></pre>

<p>Output (obviously it would be in columns in a table):</p>
<p><b>ID Title Category<br/>
11. Foo One edit<br/>
12. Bar Two edit<br/>
13. Baz Two edit<br/>
14. Faz One edit<br/>
15. Boo Two edit<br/>
First Prev 5 6 7 8 9 Next Last</b></p>

<p>Note that there are options to control how/when Prev/Next are displayed. Note also that ORDER BY link generation and datasource sorting functionality is also build-in to the core classes. I don't know that was mentioned above.)</p>
